package org.cos.verification.verifier;

import java.util.Vector;

import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

import org.cos.verification.exception.VerifierException;
import org.shellex.javame.utility.StoreManager;

public class RuleManager {
	private RecordStore rrs = null;
	
	static RuleManager instance;
	public static RuleManager getInstance() {
		if(instance == null)
			instance = new RuleManager();
		return instance;
	} 
	
	public int getRuleCount() throws VerifierException {
		try {
			return rrs.getNumRecords();
		} catch (RecordStoreNotOpenException e) {
			rrs = StoreManager.getInstance().open("cos-rule");
			throw new VerifierException("Open database fail. Please try again.");

		} 
 	}
	
	public RuleManager() {
		super();
		rrs = StoreManager.getInstance().open("cos-rule");
		//this.addRule(new Rule(12, "a", "sd", "s"));
		
	}
	
	public void shutdown(){ 
		StoreManager.getInstance().close(rrs);
	}

	public int addRule(Rule rule) throws VerifierException {
		try {
			if (this.lookupRule(rule.name) != -1) {
				throw new VerifierException("Can not Add. Record Existed.");
			}
			byte[] raw = rule.dump();
			rrs.addRecord(raw, 0, raw.length);
		} catch (RecordStoreException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
			throw new VerifierException("Can not Add. Unknown error.");
		}
		return 0;
	}
	
	public int lookupRule(String name) throws VerifierException {
		int id = -1;
		RecordEnumeration renum;
		try {
			renum = rrs.enumerateRecords(null, null, true);
			while (renum.hasNextElement()) {
				int crrId = renum.nextRecordId();
				byte[] data = rrs.getRecord(crrId);
				Rule rule = new Rule();
				rule.load(data);
				if (rule.name.equalsIgnoreCase(name)){
					return crrId;
				}
			}
		} catch (RecordStoreException e) {
			e.printStackTrace();
			throw new VerifierException("Unknown lookup rule error.");
		}
		return id;
	}
	
	public Rule setRule(Rule rule) throws VerifierException {
		try {
			int crrId = this.lookupRule(rule.name);
			if (crrId == -1) {
				throw new VerifierException("Can not set rule`" + rule.name + "'. Record does't existed.");
			}
			byte[] raw = rule.dump();
			rrs.setRecord(crrId, raw, 0, raw.length);
			return rule;
		} catch (RecordStoreException e) {
			e.printStackTrace();
			throw new VerifierException("Can not set rule`" + rule.name + "'. Unknown error.");
		}
	}
	
	public Rule getRule(int id) throws VerifierException {
		Rule rule = null; 
		try {
			rule = new Rule();
			rule.load(rrs.getRecord(id));
		} catch (RecordStoreNotOpenException e) {
			e.printStackTrace();
			rrs = StoreManager.getInstance().open("cos-rule");
			throw new VerifierException("Open database fail. Please try again.");
			
		} catch (InvalidRecordIDException e) {
			e.printStackTrace();
			return null;
		} catch (RecordStoreException e) {
			e.printStackTrace();
			throw new VerifierException("get Rule fail.");
		}
		return rule;
	}
	
	public Vector getAllRule(){
		Vector rules = new Vector();
		RecordEnumeration renum;
		try {
			System.out.println("Total Records: " + rrs.getNumRecords() );
			renum = rrs.enumerateRecords(null, null, true);
			int count = 1;
			while (renum.hasNextElement()) {
				byte[] data = renum.nextRecord();
				Rule rule = new Rule();
				rule.load(data);
				System.out.print(count + ": " + rule.name + "\n");
				rule.id = count;
				rules.addElement(rule);
				count += 1;
			}
		} catch (RecordStoreException e) {
			e.printStackTrace();
		}
		return rules;
	}
	
	public Rule removeRule(int id) throws VerifierException {
		Rule rule = null; 
		try {
			rule = new Rule();
			rule.load(rrs.getRecord(id));
			rrs.deleteRecord(id);
		} catch (RecordStoreNotOpenException e) {
			e.printStackTrace();
			rrs = StoreManager.getInstance().open("cos-rule");
			throw new VerifierException("Open database fail. Please try again.");
			
		} catch (InvalidRecordIDException e) {
			e.printStackTrace();
			return null;
		} catch (RecordStoreException e) {
			e.printStackTrace();
			throw new VerifierException("get Rule fail.");
		}
		return rule;
	}
	public Vector removeAllRule() {
		Vector rules = new Vector();
		RecordEnumeration renum;
		try {
			renum = rrs.enumerateRecords(null, null, true);
			while (renum.hasNextElement()) {
				int crrId  =  renum.nextRecordId();
				byte[] data = rrs.getRecord(crrId);
				Rule rule = new Rule();
				rule.load(data);
				System.out.println("removing: " + crrId + ", " + rule.name);
				rrs.deleteRecord(crrId);
				rule.id = crrId;
				rules.addElement(rule);		
			}
			return rules;
		} catch (RecordStoreException e) {
			e.printStackTrace();
		}
		return null;
	}
	public int importDB(String filename) {
		//TODO 从XML导入
		return 0;
	}
	public int exportDB(String filename) {
		//TODO 导出到XML
		return 0;
	}
}

